home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / dsp / piii.asm < prev    next >
Encoding:
Assembly Source File  |  1988-08-09  |  25.3 KB  |  1,061 lines

  1. ;          AMSAT/TAPR DSP BPSK demod for PIII satellites
  2. ;               Sample rate should be set to 8000 samples/sec. 
  3. ;                       code by Bob McGwier N4HY
  4. ;
  5.      org 0
  6.      b go
  7. ;
  8. ;      Okay Jose' set up equates for data memory etc.
  9. ;
  10.         org 10H  ;  code should begin at memory address 16 cause David
  11.            ;  does something strange with locations 0-15.  Does
  12.            ;  he in fact document this?
  13.     
  14. sine:   equ 0    ;  will store sine values from tone
  15. one:    equ 1      ;  guess what goes here duhhhhh!
  16. freq:   equ 2    ;  PLL frequency stored here
  17. phase:  equ 3    ;  PLL phase stored here
  18. maskl:  equ 4    ;  mask for fine or low order bits of phase
  19. mask:   equ 5    ;  mask for doing modulo 16384 arithmetic with phase
  20. sinx:   equ 6    ;  used to store coarse sine value (high order bits)
  21. cosx:   equ 7    ;  as above for cosine
  22. mone:   equ 8    ;   minus one stored here
  23. wkph:   equ 9    ;  different phases (PLL, remodulator tone etc) are stored hr
  24.                  ;  for frequency synthesis
  25. masko:  equ 10   ;  mask for converting on board PCM to DAC format
  26. mps:    equ 11   ;  multiplier for quadrant determination for sine
  27. mpc:    equ 12   ;  multiplier for quadrant determination for cosine
  28. siny:   equ 13   ;  fine correction value for use in SIN(X+Y) = sinx*cosy+
  29. cosy:   equ 14   ;          cosx*siny
  30. cosine: equ 15   ;  cosine is also needed for Q arm in Costas loop
  31. coph:   equ 16   ;  working number holder
  32. modem:  equ 17   ;  Used to choose between complex tone for arms and real tone
  33.                  ;  in the modulator as explained below
  34. bitpc:  equ 20   ;  freqo is assigned one of the values above for remod
  35.  
  36. xn0:    equ 21   ;  place  for storing all the values for the "I" or data arm
  37. xn1:    equ 22
  38. xn2:    equ 23
  39. xn3:    equ 24
  40. xn4:    equ 25
  41. xn5:    equ 26
  42. xn6:    equ 27
  43. xn7:    equ 28
  44. xn8:    equ 29
  45. xn9:    equ 30
  46. xn10:   equ 31
  47. xn11:   equ 32
  48. xn12:   equ 33
  49. xn13:   equ 34
  50. xn14:   equ 35
  51. xn15:   equ 36
  52. xn16:   equ 37
  53. xn17:   equ 38
  54. xn18:   equ 39
  55. xn19:   equ 40
  56. xn20:   equ 41
  57. xn21:   equ 42
  58. xn22:   equ 43
  59. yn0:    equ 44  ; storage for values in "Q" or phase error arm.
  60. yn1:    equ 45
  61. yn2:    equ 46
  62. yn3:    equ 47
  63. yn4:    equ 48
  64. yn5:    equ 49
  65. yn6:    equ 50
  66. yn7:    equ 51
  67. yn8:    equ 52
  68. yn9:    equ 53
  69. yn10:   equ 54
  70. yn11:   equ 55
  71. yn12:   equ 56
  72. yn13:   equ 57
  73. yn14:   equ 58
  74. yn15:   equ 59
  75. yn16:   equ 60
  76. yn17:   equ 61
  77. yn18:   equ 62
  78. yn19:   equ 63
  79. yn20:   equ 64
  80. yn21:   equ 65
  81. yn22:   equ 66
  82. c0:     equ 67  ; Phase error
  83. maskf:  equ 68  ; frequency mask so that frequency doesn't try and leave
  84.                 ; proper range
  85. H9:    equ 69
  86. H10:    equ 70  ;  arm filter value too large to use mpyk
  87. H11:    equ 71  ;  arm filter value too large to use mpyk
  88. sweep:  equ 74  ;  contains sweep value  +/- one frequency unit per sample
  89. highfq: equ 75  ;  high end of sweep range
  90. lowfq:  equ 76  ;  low end of sweep range
  91. clkfr:    equ 78
  92. clkph:    equ 79
  93. ch4:    equ 80
  94. ch5:    equ 81
  95. ch6:    equ 82
  96. bd0:    equ 83
  97. bd1:    equ 84
  98. bd2:    equ 85
  99. bd3:    equ 86
  100. bd4:    equ 87
  101. bd5:    equ 88
  102. bd6:    equ 89
  103. bd7:    equ 90
  104. bd8:    equ 91
  105. bd9:    equ 92
  106. bd10:    equ 93
  107. bd11:    equ 94
  108. bd12:    equ 95
  109. cd0:    equ 96
  110. cd1:    equ 97
  111. cd2:    equ 98
  112. cd3:    equ 99
  113. cd4:    equ 100
  114. cd5:    equ 101
  115. cd6:    equ 102
  116. cd7:    equ 103
  117. cd8:    equ 104
  118. cd9:    equ 105
  119. cd10:    equ 106
  120. cd11:    equ 107
  121. cd12:    equ 108
  122. clkav:    equ 109
  123. bit:    equ 110
  124. clock:    equ 111
  125. clocke:    equ 112
  126. bito:    equ 115
  127. bit0:    equ 18
  128. bit1:    equ 19
  129. bita0:    equ 113
  130. bita1:    equ 114
  131. clkit:  equ 116
  132. bitm0:  equ 117
  133. bitm1:  equ 118
  134. tbit:   equ 119
  135. tclk:   equ 120
  136. tfrq:   equ 121
  137. tph:    equ 122
  138. tcnt:   equ 123
  139. carof:  equ 124
  140. inty:   equ 125
  141. eom:    equ 126
  142. sintbl: dw      0  ; coarse sine table in steps of PI/64 radians to PI/2
  143.        dw    804
  144.        dw   1607
  145.        dw   2410
  146.        dw   3211
  147.        dw   4011
  148.        dw   4807
  149.        dw   5601
  150.        dw   6392
  151.        dw   7179
  152.        dw   7961
  153.        dw   8739
  154.        dw   9511
  155.        dw  10278
  156.        dw  11038
  157.        dw  11792
  158.        dw  12539
  159.        dw  13278
  160.        dw  14009
  161.        dw  14732
  162.        dw  15446
  163.        dw  16150
  164.        dw  16845
  165.        dw  17530
  166.        dw  18204
  167.        dw  18867
  168.        dw  19519
  169.        dw  20159
  170.        dw  20787
  171.        dw  21402
  172.        dw  22004
  173.        dw  22594
  174.        dw  23169
  175.        dw  23731
  176.        dw  24278
  177.        dw  24811
  178.        dw  25329
  179.        dw  25831
  180.        dw  26318
  181.        dw  26789
  182.        dw  27244
  183.        dw  27683
  184.        dw  28105
  185.        dw  28510
  186.        dw  28897
  187.        dw  29268
  188.        dw  29621
  189.        dw  29955
  190.        dw  30272
  191.        dw  30571
  192.        dw  30851
  193.        dw  31113
  194.        dw  31356
  195.        dw  31580
  196.        dw  31785
  197.        dw  31970
  198.        dw  32137
  199.        dw  32284
  200.        dw  32412
  201.        dw  32520
  202.        dw  32609
  203.        dw  32678
  204.        dw  32727
  205.        dw  32757
  206.        dw  32767  ; PI/2
  207. fines: dw      0  ; fine sine table  in steps of PI/(64*64) radians to PI/64
  208.        dw     12
  209.        dw     25
  210.        dw     37
  211.        dw     50
  212.        dw     62
  213.        dw     75
  214.        dw     87
  215.        dw    100
  216.        dw    113
  217.        dw    125
  218.        dw    138
  219.        dw    150
  220.        dw    163
  221.        dw    175
  222.        dw    188
  223.        dw    201
  224.        dw    213
  225.        dw    226
  226.        dw    238
  227.        dw    251
  228.        dw    263
  229.        dw    276
  230.        dw    289
  231.        dw    301
  232.        dw    314
  233.        dw    326
  234.        dw    339
  235.        dw    351
  236.        dw    364
  237.        dw    376
  238.        dw    389
  239.        dw    402
  240.        dw    414
  241.        dw    427
  242.        dw    439
  243.        dw    452
  244.        dw    464
  245.        dw    477
  246.        dw    490
  247.        dw    502
  248.        dw    515
  249.        dw    527
  250.        dw    540
  251.        dw    552
  252.        dw    565
  253.        dw    578
  254.        dw    590
  255.        dw    603
  256.        dw    615
  257.        dw    628
  258.        dw    640
  259.        dw    653
  260.        dw    665
  261.        dw    678
  262.        dw    691
  263.        dw    703
  264.        dw    716
  265.        dw    728
  266.        dw    741
  267.        dw    753
  268.        dw    766
  269.        dw    779
  270.        dw    791
  271. finec: dw   32767  ;ditto to above for fine sine
  272.        dw   32766
  273.        dw   32766
  274.        dw   32766
  275.        dw   32766
  276.        dw   32766
  277.        dw   32766
  278.        dw   32766
  279.        dw   32766
  280.        dw   32766
  281.        dw   32766
  282.        dw   32766
  283.        dw   32766
  284.        dw   32766
  285.        dw   32766
  286.        dw   32766
  287.        dw   32766
  288.        dw   32766
  289.        dw   32766
  290.        dw   32766
  291.        dw   32766
  292.        dw   32765
  293.        dw   32765
  294.        dw   32765
  295.        dw   32765
  296.        dw   32765
  297.        dw   32765
  298.        dw   32765
  299.        dw   32765
  300.        dw   32764
  301.        dw   32764
  302.        dw   32764
  303.        dw   32764
  304.        dw   32764
  305.        dw   32764
  306.        dw   32764
  307.        dw   32763
  308.        dw   32763
  309.        dw   32763
  310.        dw   32763
  311.        dw   32763
  312.        dw   32762
  313.        dw   32762
  314.        dw   32762
  315.        dw   32762
  316.        dw   32762
  317.        dw   32761
  318.        dw   32761
  319.        dw   32761
  320.        dw   32761
  321.        dw   32760
  322.        dw   32760
  323.        dw   32760
  324.        dw   32760
  325.        dw   32759
  326.        dw   32759
  327.        dw   32759
  328.        dw   32759
  329.        dw   32758
  330.        dw   32758
  331.        dw   32758
  332.        dw   32758
  333.        dw   32757
  334.        dw   32757
  335. armfilt: dw  5054   ; H9 
  336.          dw  7679   ; H10
  337.      dw  8706   ; H11
  338.      dw  4769   ; CH4 
  339.      dw  6557   ; CH5 
  340.      dw  7249   ; CH6 
  341. go:  ldpk 0         ; make sure that we are pointing to 0 data page
  342.      larp ar0
  343.      lark ar0,1
  344.      lark ar1,19
  345.      lack one   ; make and store one
  346.      sacl one
  347.      
  348.      lack armfilt ; store address of the too large coefficients
  349.      tblr H9
  350.      add one
  351.      tblr H10
  352.      add one
  353.      tblr H11
  354.      add one
  355.      tblr CH4
  356.      add one
  357.      tblr ch5
  358.      add one
  359.      tblr ch6
  360.      lac one,11  ; make and store DAC converter mask
  361.      sacl masko
  362.      lac one,13   ; make and store frequency mask
  363.      sub one
  364.      sacl maskf
  365.      lt one
  366.      mpyk 3072  ; 1500Hz
  367.      pac
  368.      sacl freq
  369.      lt one
  370.      mpyk 4095  ; make and store high end of sweep range
  371.      pac
  372.      sacl highfq
  373.      lt one
  374.      mpyk 2400 ; make and store low end of sweep range
  375.      pac
  376.      sacl lowfq
  377.      zac
  378.      sub one
  379.      sacl mone  ; make and store minus one
  380.      lac one,14
  381.      sub one
  382.      sacl mask  ; make and store mask for modulo 16384 phase arithmetic
  383.      lac one,6
  384.      sub one
  385.      sacl maskl ; make and store fine part of address mask;
  386.      zac
  387.      sacl inty
  388.      sacl phase
  389.      sacl clkph
  390.      sacl tph
  391.      sacl clkph
  392.      lac one
  393.      sacl sweep
  394.      lt one
  395.      mpyk 1638  ; make and store clock rate (1638 = 800 Hz)
  396.      pac
  397.      sacl clkfr
  398.      lt one
  399.      mpyk 3072
  400.      pac
  401.      sacl tfrq
  402.      
  403. ;  Okay the BS is over lets get to work !     
  404.      
  405. wait: bioz fire    ; is it time for a new sample     
  406.       b wait       ; nope go wait in the corner
  407. fire: in xn0,pa3   ; get a new sample here
  408.  
  409.      lac xn0,4
  410.      sub one,15   ; Change ADC format to two's complement
  411.      sacl xn0
  412.  
  413. ;    modulator/status/misc output
  414.  
  415.      lac bito,12
  416.      addh masko
  417.      sach yn0
  418.      out yn0,pa4   ; send bito to DAC
  419.      out bitpc,pa7 ;  output control word to PC
  420.     lac inty   ; load the PC interrupt control word
  421.      bz noi
  422.     zac        ; yes
  423.     sacl inty
  424.     out 6,6   ; tell the PC that we are ready
  425.  
  426. ;    end output
  427.  
  428. ;    Determine transmit bit timing
  429.  
  430. noi: larp 1   ; transmit timing auxiliary register
  431.      banz noty ;  is time to tick the clock for the PC?
  432.  
  433.      lark ar1,19  ; yes,reset output bit counter
  434.      zac
  435.      sacl tcnt    ; reset Manchester (split phase) counter
  436.      lac one,2    ; get ready to tick the clock in the PC control word
  437.      sacl c0
  438.      lac bitpc    ; load the control word
  439.      xor c0       ; tick the <TX> clock
  440.      sacl bitpc   ; store the new PC control word
  441.      lac inty
  442.      or one
  443.      sacl inty
  444.      in  c0,7     ; input the PC side control word
  445.      lac one,4
  446.      and c0       ; pick off the eye or modulator control bit
  447.      sacl eom
  448.      lac one,3    ; pick off the transmit bit
  449.      and c0
  450.      bgz tpo      ; is it zero ?
  451.      lac mone     ; yes set bit multiplier to minus one
  452.      sacl tbit
  453.      b noty
  454. tpo: lac one      ; No it is a one so set the multiplier to one
  455.      sacl tbit
  456.  
  457. noty: 
  458.     
  459.  
  460. ;    Manchester the bit
  461.  
  462.      lac tcnt    ; Find out if we are half way through the bit
  463.      sub one,3
  464.      sub one,2   ; if tcnt is ten, it is time to split the bit
  465.      bnz dnch    ; if we are not half way, don't change it
  466.      lt mone     ;  We are halfway so change the sign of the bit multiplier
  467.      mpy tbit
  468.      pac
  469.      sacl tbit
  470. dnch: lac tcnt   
  471.      add one     ;  Increment ther Manchester (split phase) counter
  472.      sacl tcnt
  473.  
  474. ;    Begin modulator
  475.      lac eom
  476.      bnz eye
  477.      lac mone
  478.      sacl modem ; real tone
  479.      lack one  ;
  480.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  481.      sacl mpc  ;
  482.      lac tph  
  483.      add tfrq ; increment the modulator phase, tph, by the modulator frq, tfrq
  484.      and mask
  485.      sacl tph
  486.      call tones  ; get the sinusoid
  487.      lt sine
  488.      mpy tbit   ; multiply by the bit
  489.      pac
  490.      sacl bito  ; store for the DAC  to output to the transmitter
  491.  
  492.  
  493. ;    Begin demodulator
  494. eye: lack one
  495.      sacl modem  ; store control that makes complex tone
  496.      lack one  ;
  497.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  498.      sacl mpc  ;
  499.      lac phase
  500.      call tones ; go make complex tone
  501.  
  502.      lt xn0  ; load the current sample
  503.      mpy cosine; multiply by cosine
  504.      pac
  505.      sach yn0,1 ; store it Q channel current sample
  506.      mpy sine ; multiply sample by sine
  507.      pac
  508.      sach xn0,1 ; now store it in current sample place for I channel
  509.      
  510. ;     Low pass for each sample cutoff is at 800 Hz. Carrier is 20-25 dB down
  511.  
  512. ;     First lowpass I arm product to get the lower frequency mixer products
  513.  
  514.      zac
  515. ;
  516.      lt xn22
  517.      mpyk -117
  518. ;
  519.      ltd xn21
  520.      mpyk 675
  521. ;
  522.      ltd xn20
  523.      mpyk 647
  524. ;
  525.      ltd xn19
  526.      mpyk 325
  527. ;
  528.      ltd xn18
  529.      mpyk -453
  530. ;
  531.      ltd xn17
  532.      mpyk -1303
  533. ;
  534.      ltd xn16
  535.      mpyk -1513
  536. ;
  537.      ltd xn15
  538.      mpyk -459
  539. ;
  540.      ltd xn14
  541.      mpyk 1949
  542. ;
  543.      ltd xn13
  544.      mpy H9
  545. ;
  546.      ltd xn12
  547.      mpy H10
  548. ;
  549.      ltd xn11
  550.      mpy H11
  551. ;
  552.      ltd xn10
  553.      mpy H10
  554. ;
  555.      ltd xn9
  556.      mpy H9
  557. ;
  558.      ltd xn8
  559.      mpyk 1949
  560. ;
  561.      ltd xn7
  562.      mpyk -459
  563. ;
  564.      ltd xn6
  565.      mpyk -1513
  566. ;
  567.      ltd xn5
  568.      mpyk -1303
  569. ;
  570.      ltd xn4
  571.      mpyk -453
  572. ;
  573.      ltd xn3
  574.      mpyk 325
  575. ;
  576.      ltd xn2
  577.      mpyk 647
  578. ;
  579.      ltd xn1
  580.      mpyk 675
  581. ;
  582.      ltd xn0
  583.      mpyk -117
  584. ;
  585.      apac
  586. ;
  587.      sach xn0,1
  588.      
  589. ;  Now do the Q arm to get the lower frequency mixer products.
  590.  
  591.      zac
  592. ;
  593.      lt yn22
  594.      mpyk -117
  595. ;
  596.      ltd yn21
  597.      mpyk 675
  598. ;
  599.      ltd yn20
  600.      mpyk 647
  601. ;
  602.      ltd yn19
  603.      mpyk 325
  604. ;
  605.      ltd yn18
  606.      mpyk -453
  607. ;
  608.      ltd yn17
  609.      mpyk -1303
  610. ;
  611.      ltd yn16
  612.      mpyk -1513
  613. ;
  614.      ltd yn15
  615.      mpyk -459
  616. ;
  617.      ltd yn14
  618.      mpyk 1949
  619. ;
  620.      ltd yn13
  621.      mpy H9
  622. ;
  623.      ltd yn12
  624.      mpy H10
  625. ;
  626.      ltd yn11
  627.      mpy H11
  628. ;
  629.      ltd yn10
  630.      mpy H10
  631. ;
  632.      ltd yn9
  633.      mpy H9
  634. ;
  635.      ltd yn8
  636.      mpyk 1949
  637. ;
  638.      ltd yn7
  639.      mpyk -459
  640. ;
  641.      ltd yn6
  642.      mpyk -1513
  643. ;
  644.      ltd yn5
  645.      mpyk -1303
  646. ;
  647.      ltd yn4
  648.      mpyk -453
  649. ;
  650.      ltd yn3
  651.      mpyk 325
  652. ;
  653.      ltd yn2
  654.      mpyk 647
  655. ;
  656.      ltd yn1
  657.      mpyk 675
  658. ;
  659.      ltd yn0
  660.      mpyk -117
  661. ;
  662.      apac
  663. ;
  664.      sach yn0,1
  665.  
  666. ;  Okay we now have filtered products with data bauding pseudo base banded
  667. ;  Let's close the loop and lock on
  668.  
  669.      lac xn0;  Hard limit data line for phase error detector
  670.      sacl bd0;  Input data into delay line so that demanchester can occur at
  671.              ;  Zero crossing.
  672.      bgez pdps  ; is data baud a plus one ?
  673.      lt yn0     ; get ready for a multiply
  674.      mpyk -1    ; multiply phase error arm by -1
  675.      pac
  676.      sacl yn0
  677. pdps: lt carof
  678.      mpyk 7     ; leaky integrate the phase error
  679.      pac 
  680.      sacl cosy
  681.      lac carof,15
  682.      add cosy,12  ; take 7/8 of the old value and add it to the gain times
  683.      add yn0,10   ; the current phase error observation. (LPF)
  684.      sach carof
  685. ;;    lac carof,3  ;  uncomment these two lines to send the
  686. ;;    sacl bito  ;  VCO error voltage out the D/A
  687.      lac yn0,10  ; add a small amount of the current phase error to
  688.      addh carof  ; the integrator output.
  689.      sach c0     ; this is the phase correction
  690.      lac c0      ;  load correction
  691. delph: add phase   ; add the old phase 
  692.      add freq    ; add the phase increment (frequency)
  693.      and mask    ; modulo 2*pi
  694.      sacl phase  ; store it for next sample complex tone generation step
  695.     lac eom
  696.     bz mod
  697.     lac xn0     ; uncomment these two lines to send eye patterns out
  698.     sacl bito   ; the D/A port
  699. ;    lac sine,11 ; uncomment these two to hear recovered carrier.
  700. ;    sach bito
  701.  
  702.  
  703. ;    Assuming lock, let's recover clock using a PLL on a nonlinearity
  704. ;    generating a clock tone
  705.  
  706. mod: lt xn0
  707.      mpy xn0    ; square the current data arm value
  708.      pac
  709.      apac
  710.      apac       ; add it to the accumulator three times to raise the number
  711.         ; of significant bits in the high word
  712.      sach cd0,1 ; shift left 4 and store the high word
  713.      lt clkav
  714.      mpyk 3    ; we will LPF with an exponential decay filter to estimate
  715.      pac        ;  the average amplitude of the clock signal.  Multiply old
  716.      sacl cosy
  717.      lac cd0,13 ; load one sixteenth of the current clock signal value
  718.      abs
  719.      add clkav,15  ; value first by fifteen and then divide by 16.
  720.      add cosy,13
  721.      sach clkav
  722.      lac cd0,2     ;load it shifting one up to increase significance
  723.      sub clkav,2
  724.      sacl cd0      ; subtract the average value, that is remove the DC.
  725. ;    sacl bito
  726.      lac mone  
  727.      sacl modem ; real tone
  728.      lack one  ;
  729.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  730.      sacl mpc  ;
  731.      lac one,12    ;  we are going to use the tone generator and we need
  732.      sub clkph     ; cosine so take pi/2 - phase and then find the sine of
  733.      add one,14    ; that after doing mod 2*pi
  734.      and mask
  735.      call tones    ; get the cosine  (which will be the sine since we did
  736. ;    lac sine,11
  737. ;    sach bito  ; un comment these two lines to see the clock tone
  738.      lt sine       ; complimentary angle
  739.      mpy cd0       ; multiply by the current clock tone value
  740.      pac          
  741.      sach cd0,1
  742.  
  743. ;    filter this product to get the clock signal phase error 
  744. ;    sine(clock phase)*cosine(clock phase estimate) yields the error signal
  745. ;    LP Filter to get the lower frequency mixer products
  746. ;    Filter with cutoff at 800 Hz, doesn't need to be a great filter, just
  747. ;    the best you can do in 13 taps.  25+ dB rejection of the stuff at
  748. ;    1600.
  749.  
  750.      lt cd12
  751.      mpyk -930
  752.      pac
  753.      
  754.      ltd cd11
  755.      mpyk -293
  756.      apac
  757.      dmov bd11
  758.      
  759.      ltd cd10
  760.      mpyk 732
  761.      apac
  762.      dmov bd10
  763.      
  764.      ltd cd9
  765.      mpyk 2571
  766.      apac
  767.      dmov bd9
  768.      
  769.      ltd cd8
  770.      mpy ch4
  771.      apac
  772.      dmov bd8
  773.      
  774.      
  775.      ltd cd7
  776.      mpy ch5
  777.      apac
  778.      dmov bd7
  779.      
  780.      ltd cd6
  781.      mpy ch6
  782.      apac
  783.      dmov bd6
  784.      
  785.      ltd cd5
  786.      mpy ch5
  787.      apac
  788.      dmov bd5
  789.      
  790.      ltd cd4
  791.      mpy ch4
  792.      apac
  793.      dmov bd4
  794.      
  795.      ltd cd3
  796.      mpyk 2571
  797.      apac
  798.      dmov bd3
  799.       
  800.      ltd cd2
  801.      mpyk 732
  802.      apac
  803.      dmov bd2
  804.      
  805.      ltd cd1
  806.      mpyk -293
  807.      apac
  808.      dmov bd1
  809.      
  810.      ltd cd0
  811.      mpyk -930
  812.      apac
  813.      dmov bd0
  814.      
  815.      sach clocke
  816.  
  817.      lt clkit
  818.      mpyk 15   ; SLOW leak integrator,  31/32 old phase error plus
  819.      pac
  820.      sacl cosy
  821. ;     lac clkit,15
  822.      lac cosy,12
  823. ;     add cosy,11
  824. ;     lac clkit,11 
  825.      add clocke,11  ;   1/32 of the new phase error estimate
  826.      sach clkit
  827.      lac clocke,10  ;   add 1/32 of the current phase error observation to
  828.      add clkit,15     ;   the integrated estimate
  829.      sach clocke
  830.      lac clocke     ;   load phase correction
  831.     
  832. dlcph: add clkph   ; add the old phase 
  833.      add clkfr    ; add the phase increment (frequency)
  834.      sacl clkph
  835.      sub 1,14     ; if the phase is greater than two pi, we have hit a
  836.      blz wait     ; baud boundary, if not, go back to wait and start over
  837.  
  838. ;    We have crossed a baud boundary since the phase is >= 2^14.
  839.  
  840.      sacl clkph  ; store it for next sample complex tone generation step
  841. ;
  842. ;    We have had to comprimise.  The most we could fit, due to constraints
  843. ;       of 128 data memory data locations in page 0, is just over half the total
  844. ;       bit into our delay line.  HOWEVER, this is "the important half"
  845. ;       It is the center and contains the "peaks" around the guaranteed
  846. ;       zero crossing in the center of the bit.  Convolve with the bit shape
  847. ;       and get 0 or 1.
  848. ;
  849.      ; de Manchester the bits in the delay line
  850.      lt bd12
  851.      mpyk 1024
  852.      pac
  853.      lt bd11
  854.      mpyk 4095
  855.      apac
  856.      lt bd10
  857.      mpyk 4095
  858.      apac
  859.      lt bd8
  860.      mpyk 1024
  861.      apac
  862.      lt bd7
  863.      mpyk 128
  864.      apac
  865.      lt bd5
  866.      mpyk -128
  867.      apac
  868.      lt bd4
  869.      mpyk -1024
  870.      apac
  871.      lt bd2
  872.      mpyk -4095
  873.      apac
  874.      lt bd1
  875.      mpyk -4095
  876.      apac
  877.      lt bd0
  878.      mpyk -1024
  879.      apac
  880.      sach bit,4   ; Store the de-Manchestered bit
  881. ;    There is an ambiguity in the clock since the clock tone recovery
  882. ;    above runs at 800 Hz.  We must decide which is the REAL bit center
  883. ;    and then output that bit determined above.  This is a statistical
  884. ;    process.  We are guaranteed a bit transition in center of each
  885. ;    bit.   If we are on the boundary, the occasional change from a zero
  886. ;    to a one and vice versa causes NO transition.  The process above
  887. ;    Will yield a small positive number for abs(bit) when there is no
  888. ;    transition
  889.      lac bit
  890.      larp 0      ; set auxiliary register pointer to the receive clock control.
  891.          ; <RX> clock control register
  892.      banz b1     ; is it bit time 0 or bit time 1
  893.      bgz psb0    ; it is bit time zero.  Is the bit positive?
  894.      lac mone,10    ; No  load -1
  895.      sacl bit0   ; and store it in bit 0
  896.      b rar0
  897. psb0: lac one,10
  898.      sacl bit0 
  899. rar0: lark ar0,1  ; reset the counter  for the next two 2pi crossings.
  900.      lac bit      ; load bit for the bit time 0, take absolute value
  901.      abs
  902.      sacl bita0   ; store it for later
  903.      b wait
  904. ;    The bit time was 1 and not zero.
  905. b1:  bgz psb1   ; is bit positive?
  906.      lac mone,10   ; no so load -1
  907.      sacl bit1  ; store it in bit one
  908.      b rar1
  909. ;    yes it is positive
  910. psb1: lac one,10   ; load one
  911.      sacl bit1  ; store it in bit one
  912. rar1: lac bit   ; load bit for the bit time 1, take absolute value
  913.      abs
  914.      sacl bita1 ; store it for later
  915.      lack 13    ;  load the accumulator with 1101  binary
  916.      and bitpc  ;  use it mask the PC control word to destroy old bit.
  917.      xor one    ; tick the output clock
  918.      sacl bitpc ; store it
  919.      lac inty
  920.      or one     ; setup to interrupt PC with new control word
  921.      sacl inty
  922.      lac bita1  ;  load the bit1 size
  923.      sub bita0  ;  sub the bit0 size
  924.      add bitm0  ;  integrate
  925.      sacl bitm0 ; store it
  926.      sub 1,12  ; let 4096 be the rails
  927.      bgz th   ; are we greater than 4096?
  928.      lac bitm0 ; load it again
  929.      add 1,12   ; add 4096
  930.      blz tl    ; still less than zero?  < -4096?
  931.      b dbt
  932. ;   Yes we are greater than 4096, so make us 4096
  933. th:  lac 1,12
  934.      sacl bitm0
  935.      b dbt
  936. ;   Yes we are less than -4096, so make us -4096
  937. tl:  zac
  938.      sub one,12   ; load -4096
  939.      sacl bitm0  ; store it
  940. dbt: lt bitm1 
  941.      mpyk 7   ; average with 31/32 times old + 1/32 * new
  942.      pac
  943.      sacl cosy
  944.      lac bitm1,15
  945.      lac cosy,12
  946.      add bitm0,11
  947.      sach bitm1
  948.      lac bitm1
  949. ;    sacl bito  ; uncomment to see which clock phase was chosen for
  950.            ; the true center of bit
  951.      blz bi0  ; is the averaged size of bit0 bigger?
  952. ; NO
  953.      lac bit1 ; load bit 1
  954.      b outb   ; jump to modify PC control word
  955. bi0: lac bit0
  956. outb: 
  957. ;    sacl bito     ; uncomment to send bits out the D/A port
  958.      blz wait ; if the bit is negative, bitpc is already setup
  959.      lac one,1 ; if not we need to add a 1 in the 2's spot, i.e. add 2.
  960.      or bitpc
  961.      sacl bitpc ; store it in the PC control word
  962. outp: b wait         ; go output and then do it again
  963.  
  964. ;     complex tone generator if modem>0 if modem<0 sine wave generator
  965.  
  966. tones: sacl wkph  ;  store a working copy
  967.      lac wkph,4
  968.      subh one
  969.      blz getem  ;  is it in a quadrant bigger than first?
  970.      subh one
  971.      bgez thfr; is it in a quadrant greater than two?
  972.      lac 1,13  ;  nope so load pi
  973.      sub wkph  ;  subtract phase so that it maps back into 1st quad
  974.      sacl wkph ; store
  975.      lac mone  ; load -1
  976.      sacl mpc  ; store it in the cosine multiplier
  977.      b getem   ; go read tables
  978. thfr: lac mone  ; multiplier for bottom half
  979.      sacl mps  ; store
  980.      lac wkph  ; 
  981.      sub one,13 ; map angle back to  upper half and go do it again
  982.      b tones
  983. getem: lac wkph,10 ; take 1st quadrant phase equiv for sine and pick 
  984.                    ; off coarse part of phase address
  985.      sach coph     ; store it
  986.      lack sintbl   ;  load sine table offset into accumulator
  987.      add coph      ; add coarse address off set
  988.      tblr sinx     ; read the coarse sine value
  989.      lac one,6     ;  load pi/2
  990.      sub coph      ; subtract the coarse phase to get cosines offset
  991.      sacl coph      
  992.      lack sintbl
  993.      add coph      ; do same as above for coarse cosine
  994.      tblr cosx
  995.      lac wkph      ; load working phase
  996.      and maskl     ;  mask off fine addres
  997.      sacl coph     ; store it
  998.      lack fines    ; locate fine table offset
  999.      add coph      ; add for offset into fine table
  1000.      tblr siny     ;  read table
  1001.      lack finec
  1002.      add coph
  1003.      tblr cosy
  1004.      zac
  1005.      lt sinx       ; load sinx
  1006.      mpy cosy      ;  multiply by cosy
  1007.      lta siny      ; load t reg with fine sin and accumulate previous prod.
  1008.      mpy cosx      ; multiply by coarse cosx to use sin(X+Y)
  1009.      apac          ; add the result to coarse sine
  1010.      sach sine     ; store it.
  1011.      lac modem 
  1012.      blz mult
  1013.      lac 1,12      ; load full address pi/2
  1014.      sub wkph      ; subtract the working phase to get cosine
  1015.      sacl wkph 
  1016.      lac wkph,10   ;  from here to the later MARK it is identical to above
  1017.      sach coph
  1018.      lack sintbl
  1019.      add coph
  1020.      tblr sinx
  1021.      lac one,6
  1022.      sub coph
  1023.      sacl coph
  1024.      lack sintbl
  1025.      add coph
  1026.      tblr cosx
  1027.      lac wkph
  1028.      and maskl
  1029.      sacl coph
  1030.      lack fines
  1031.      add coph
  1032.      tblr siny
  1033.      lack finec
  1034.      add coph
  1035.      tblr cosy
  1036.      zac
  1037.      lt cosy
  1038.      mpy sinx
  1039.      lta siny
  1040.      mpy cosx
  1041.      apac  ; MARK
  1042.      sach cosine ; store it in the cosine
  1043. mult: lt mps;  now we need to do a few multiplies by sign changes due to
  1044.      mpy sine ; to quadrant part of phase address
  1045.      pac;     multiply sine by sine sign (:-)  and
  1046.      sacl sine ;  store the result
  1047.      lac modem
  1048.      bgz cosm
  1049.      ret
  1050. cosm: mpy cosine;  now multiply cosine by the same
  1051.      pac
  1052.      sacl cosine ; store it
  1053.      lt mpc;  load cosine differentiator from sine sign (:-)
  1054.      mpy cosine;  multiply
  1055.      pac
  1056.      sacl cosine ; store
  1057.      ret
  1058.      end
  1059. ;  Ebbly Ebbly Ebbly thats all folks
  1060.  
  1061.